package com.xzcs.util.mail;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;
import java.util.Date;
import java.util.List;
import java.util.Properties;

public class EmailSendUtils {
    public final Logger log = LoggerFactory.getLogger(this.getClass());
    private MimeMessage message; // MIME邮件对象
	private Session session; // 邮件会话对象
    private Properties properties; // 系统属性
    private String username = ""; // smtp认证账户
    private String password = ""; // smtp认证账户密码
    private Multipart mp; // Multipart对象,邮件内容,标题,附件等内容均添加到其中后再生成MimeMessage对象
    private boolean sslFlag = false;//是否使用ssl发送
    
    public EmailSendUtils(boolean sslFlag){
    	this.sslFlag = sslFlag;
    }

    /**
     * 构造函数
     * @param smtpHost
     * @param smtpPort
     * @param sslFlag
     */
    public EmailSendUtils(String smtpHost, String smtpPort, boolean sslFlag) {
        this.setSmtpHost(smtpHost, smtpPort);
        this.createMimeMessage();
        this.sslFlag = sslFlag;
    }

    /** 
     * 设置SMTP主机
     * @param smtpHost
     * @param smtpPort
     */ 
    public void setSmtpHost(String smtpHost, String smtpPort) {
        log.debug("mail.smtp.host = " + smtpHost);
        log.debug("mail.smtp.port = " + smtpPort);
        if(properties == null) {
            properties = System.getProperties(); // 获得系统属性对象
        }
        properties.put("mail.smtp.host", smtpHost); // 设置SMTP主机
        properties.put("mail.smtp.port", smtpPort); // 设置SMTP主机端口
        
        if (sslFlag) {
        	properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");  
            properties.setProperty("mail.smtp.socketFactory.fallback", "false");  
            properties.setProperty("mail.smtp.socketFactory.port", smtpPort);  
		}
    }

    /** 
     * 创建邮件会话
     * @return
     */ 
    public boolean createMimeMessage() {
        try {
            log.debug("准备获取邮件会话对象！");
            session = Session.getInstance(properties); // 获得邮件会话对象
        } catch (Exception e) {
            log.debug("获取邮件会话对象时发生错误！" + e);
            return false;
        }

        log.debug("准备创建MIME邮件对象！");
        try {
            message = new MimeMessage(session); // 创建MIME邮件对象
            mp = new MimeMultipart();
            return true;
            
        } catch (Exception e) {
            log.debug("创建MIME邮件对象失败！" + e);
            return false;
        }
    }

    /** 
     * 设置
     * @param need
     */ 
    public void setNeedAuth(boolean need) {
        log.debug("设置smtp身份认证：mail.smtp.auth = " + need);
        if(properties == null) {
            properties = System.getProperties();
        }
        if(need) {
            properties.put("mail.smtp.auth", "true");
        } else {
            properties.put("mail.smtp.auth", "false");
        }
    }

    /**
     * 发信人邮箱名称和密码
     * @param name
     * @param pass
     */
    public void setNamePass(String name, String pass) {
        username = name;
        password = pass;
    }

    /** 
     * 设置邮件主题
     * @param mailSubject
     * @return
     */ 
    public boolean setSubject(String mailSubject) {
        log.debug("设置邮件主题");
        try {
            message.setSubject(mailSubject);
            return true;
        } catch (Exception e) {
            log.debug("设置邮件主题发生错误！");
            return false;
        }
    }

    /** 
     * 设置发送时间
     * @param date
     * @return
     */ 
    public boolean setDate(Date date) {
        log.debug("设置发送时间");
        try {
            message.setSentDate(date);
            return true;
        }
        catch (Exception e) {
            log.debug("设置发送时间发生错误！");
            return false;
        }
    }

    /** 
     * 设置邮件正文
     * @param mailBody
     * @return
     */ 
    public boolean setBody(String mailBody) {
        try {
            BodyPart bodyPart = new MimeBodyPart();
            bodyPart.setContent("" + mailBody, "text/html;charset=UTF-8");
            mp.addBodyPart(bodyPart);
            return true;
        } catch (Exception e) {
            log.debug("设置邮件正文时发生错误！" + e.toString());
            return false;
        }
    }

    /** 
     * 邮件添加附件
     * @param filename
     * @return
     */ 
    public boolean addFileAffix(String filename) {
        log.debug("增加邮件附件：" + filename);
        try {
            BodyPart bp = new MimeBodyPart();
            FileDataSource fileds = new FileDataSource(filename);
            bp.setDataHandler(new DataHandler(fileds));
            bp.setFileName(MimeUtility.encodeWord(fileds.getName()));
            mp.addBodyPart(bp);
            return true;
        } catch (Exception e) {
            log.debug("增加邮件附件：" + filename + "发生错误！" + e);
            return false;
        }
    }
    
    /** 
     * 邮件添加附件
     * @param filename
     * @return
     */ 
    public boolean addFileAffix(String filepath, String filename) {
        log.debug("增加邮件附件：" + filename);
        try {
            BodyPart bp = new MimeBodyPart();
            FileDataSource fileds = new FileDataSource(filepath);
            bp.setDataHandler(new DataHandler(fileds));
            bp.setFileName(MimeUtility.encodeWord(filename));
            mp.addBodyPart(bp);
            return true;
        } catch (Exception e) {
            log.debug("增加邮件附件：" + filename + "发生错误！" + e);
            return false;
        }
    }

    /** 
     * 设置发信人
     * @param from
     * @return
     */ 
    public boolean setFrom(String from) {
        log.debug("设置发信人！");
        try {
            message.setFrom(new InternetAddress(from)); // 设置发信人
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    
    /** 
     * 设置收件人
     * @param to
     * @return
     */ 
    public boolean setTo(String to) {
        if(to == null) {
        	return false;
        }
        try {
            message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to));
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    /** 
     * 设置抄送人
     * @param copyto
     * @return
     */ 
    public boolean setCC(String copyto) {
        if(copyto == null) {
            return false;
        }
        try {
            message.setRecipients(Message.RecipientType.CC, (Address[]) InternetAddress.parse(copyto));
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    /** 
     * 设置密送人
     * @param copyto
     * @return
     */ 
    public boolean setBCC(String copyto) {
        if(copyto == null) {
            return false;
        }
        try {
            message.setRecipients(Message.RecipientType.BCC, (Address[]) InternetAddress.parse(copyto));
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    /** 
     * 邮件发送
     * @return
     */ 
    public boolean sendEmail() {
        try {
            message.setContent(mp);
            message.saveChanges();
            log.debug("========= 正在发送邮件... ==========");
            Session mailSession = Session.getInstance(properties, null);
            Transport transport = mailSession.getTransport("smtp");
            transport.connect((String) properties.get("mail.smtp.host"), username, password);
            transport.sendMessage(message, message.getRecipients(Message.RecipientType.TO));
            transport.sendMessage(message, message.getRecipients(Message.RecipientType.CC));
            transport.sendMessage(message, message.getRecipients(Message.RecipientType.BCC));
            transport.close();
            log.debug("========= 发送邮件成功！==========");
            return true;
        } catch (Exception e) {
            log.debug("邮件发送失败！" + e.toString());
            return false;
        }
    }
    
    /** 
     * 邮件发送
     * @return
     */ 
    public boolean sendEmail(String smtpHost, String smtpPort, boolean needAuth, String senderAuth,
            String senderPwd, String toUser, String ccUser, String bccUser, String mailSubject, String mailBody,
            List<String> attachmentList) {
        try {
            this.setSmtpHost(smtpHost, smtpPort);
            this.createMimeMessage(); 
            this.setNamePass(senderAuth, senderPwd);
            this.setNeedAuth(needAuth);
            
            if(this.setSubject(mailSubject) == false) { //设置邮件标题
                return false;
            }
            if(this.setBody(mailBody) == false) { //设置邮件内容
                return false;
            }
            if(this.setFrom(senderAuth) == false) { //设置发件人
                return false;
            }
            if(this.setTo(toUser) == false) { //设置收件人
                return false;
            }
            if(this.setCC(ccUser) == false) { //设置抄送人
                return false;
            }
            if(this.setBCC(bccUser) == false) { //设置密送人
                return false;
            }
            //设置附件
            if(attachmentList != null && !attachmentList.isEmpty()) {
                for(int i = 0; i < attachmentList.size(); i++) {
                    if(this.addFileAffix(attachmentList.get(i)) == false) { //设置附件
                        return false;
                    }
                }
            }
            
            message.setContent(mp);
            message.saveChanges();
            
            log.debug("========= 正在发送邮件... ==========");
            Session mailSession = Session.getInstance(properties);
            Transport transport = mailSession.getTransport("smtp");
            transport.connect((String) properties.get("mail.smtp.host"), username, password);
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
            log.debug("========= 发送邮件成功！==========");
            return true;
        } catch (Exception e) {
            log.debug("邮件发送失败！" + e.toString());
            return false;
        }
    }
    
    public static void main(String[] args) {
    	EmailSendUtils mailSendUtils = new EmailSendUtils(true);
        String content = "<style type='text/css'>div{color:red}</style><div>测试正文邮件</div>";

        mailSendUtils.sendEmail("smtp.exmail.qq.com", "465", true, "changs@njruiyue.cn", "cs19870115",
        		"changshuai_0115@163.com", "", "", "测试邮件ssl", content, null);
    }
}